﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace BMPTOPNG
{
    public class ImageUtil
    {
        public static void ConvertToPNG3(string filePath)
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                //判断像素深度, 仅对32-bit BMP操作
                fs.Position = 0x1C;
                byte[] byteDepth = new byte[4];
                fs.Read(byteDepth, 0, 4);
                int depth = BitConverter.ToInt32(byteDepth, 0);
                if (depth != 32)
                {
                    Console.Write("Not 32-bit bmp file.\n");
                    return;
                }
                else
                {
                    DateTime dt = DateTime.Now;

                    //Pixel数据区开始位置
                    fs.Position = 0xA;
                    byte[] bytePixelArrayStart = new byte[4];
                    fs.Read(bytePixelArrayStart, 0, 4);
                    int posPixelArrayStart = BitConverter.ToInt32(bytePixelArrayStart, 0);

                    //图片宽度
                    fs.Position = 0x12;
                    byte[] byteWidth = new byte[4];
                    fs.Read(byteWidth, 0, 4);
                    int width = BitConverter.ToInt32(byteWidth, 0);

                    //图片高度
                    fs.Position = 0x16;
                    byte[] byteHeight = new byte[4];
                    fs.Read(byteHeight, 0, 4);
                    int height = BitConverter.ToInt32(byteHeight, 0);

                    fs.Position = posPixelArrayStart;
                    //建立一个与原图等大的Bitmap对象, 设置像素格式为32-bitARGB
                    using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
                    {
                        //获取该Bitmap对象的BitmapData数据
                        BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bmp.PixelFormat);
                        //获取数据开始的指针
                        IntPtr ptr = bmpData.Scan0;
                        //计算数据区的长度
                        int imgLen = Math.Abs(bmpData.Stride) * bmp.Height;
                        byte[] pixels = new byte[imgLen];

                        //逐个Byte读取值并写入对应像素的各个通道
                        for (int counter = 0; counter < pixels.Length; counter++)
                        {
                            byte[] color = new byte[1];
                            fs.Read(color, 0, 1);
                            pixels[counter] = color[0];
                        }

                        //直接将新的Pixel数据复制入BitmapData对象, 覆盖原有数据
                        System.Runtime.InteropServices.Marshal.Copy(pixels, 0, ptr, imgLen);
                        bmp.UnlockBits(bmpData);

                        //这样生成的图时y方向上下颠倒的, 需要做一次翻转
                        //这样的翻转不会导致图片质量的损失
                        bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);

                        //转换成PNG格式并写入新文件
                        string pngFile = string.Format(@"{0}\{1}.png", Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                        bmp.Save(pngFile, ImageFormat.Png);

                        Console.Write("Used: {0}ms.\n", (DateTime.Now - dt).TotalMilliseconds);
                    }
                }
            }
        }

        public static void ConvertToPNG(string filePath)
        {
            using (Bitmap bitmap = new Bitmap(filePath))
            {
                int width = bitmap.Width;
                int height = bitmap.Height;
                Bitmap newBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                for (int wIndex = 0; wIndex < width; wIndex++)
                {
                    for (int hIndex = 0; hIndex < height; hIndex++)
                    {
                        Color pixelColor = bitmap.GetPixel(wIndex, hIndex);
                        if (pixelColor.R == 0 && pixelColor.G == 0 && pixelColor.B == 0)
                        {
                            newBitmap.SetPixel(wIndex, hIndex, Color.FromArgb(0, 0, 0, 0));
                        }
                        else
                        {
                            newBitmap.SetPixel(wIndex, hIndex, pixelColor);
                        }
                    }
                }

                string pngFile = string.Format(@"{0}\{1}.png", Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));

                newBitmap.Save(pngFile, ImageFormat.Png);
                newBitmap.Dispose();
            }
        }


        public static void ConvertToPNG(string filePath, string destDir)
        {
            using (Bitmap bitmap = new Bitmap(filePath))
            {
                int width = bitmap.Width;
                int height = bitmap.Height;
                Bitmap newBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                for (int wIndex = 0; wIndex < width; wIndex++)
                {
                    for (int hIndex = 0; hIndex < height; hIndex++)
                    {
                        Color pixelColor = bitmap.GetPixel(wIndex, hIndex);
                        if (pixelColor.R == 0 && pixelColor.G == 0 && pixelColor.B == 0)
                        {
                            newBitmap.SetPixel(wIndex, hIndex, Color.FromArgb(0, 0, 0, 0));
                        }
                        else
                        {
                            newBitmap.SetPixel(wIndex, hIndex, pixelColor);
                        }
                    }
                }

                string pngFile = string.Format(@"{0}\{1}.png", destDir, Path.GetFileNameWithoutExtension(filePath));

                newBitmap.Save(pngFile, ImageFormat.Png);
                newBitmap.Dispose();
            }
        }
    
    }
}